/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#ifndef __DATA_STRUCT_CONNECTION_H__
#define __DATA_STRUCT_CONNECTION_H__

#include "../tools/thread_lock.h"
#include "tcp.h"
#include "udp.h"

namespace xos_net
{

    class connection : public xos_stl::mem_item< xos::release_impl< connection >, thread_lock >,
        public xos_aio::i_connect,
        public net::i_connect
    {
    public:
        typedef xos::release_impl< connection > T;

    public:
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 
        enum class enumState
        {
            STATE_NONE,

            STATE_CONNECT_FAILED,
            STATE_CONNECTING,
            STATE_INIT_FAILED,
            STATE_INITING,
            STATE_RUNNING,
            STATE_CLOSING,
            STATE_CLOSED,

            STATE_NEED_CLOSE,
            STATE_TIME_OUT,

            STATE_END
        };
        enum class enumType
        {
            TYPE_NONE,

            TYPE_TCP_LISTEN,
            TYPE_TCP_DATA,
            TYPE_UDP,

            TYPE_END
        };

    public:
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 
        connection();
        ~connection();

    public:
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 
        static int get_xos_item_data( ITEM_DATA *& item_ptr );
        static int static_user_init();
        static int static_user_term();

    public:
        static xos_box::i_all_done_test * done_test();
        static bool done_test_server();
        static int stop_all_connect();
        static int stop_all_server();
        static int heart();

    protected:
        static int check_timeout( connection * pCon );

    public:
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 

        // 连接的引用计数
        xos_box::i_lock_num * m_pRefNum;

        // 离超时，还有的毫秒数
        int net_timeout_ms;

        // 连接在连接列表中的位置
        connection::ITER m_connect_iter;
        enumState m_eState;
        enumType m_eType;

        // 自己发出的客户端连接关掉时，不清除。
        // 接受到的连接关闭时都会清除。
        // 默认清除
        bool m_bReleaseAfterClose;

        // io允许状态，调用shutdown可以禁用读写
        int m_nReadWritePermmit;

        // tcp or udp
        connection * m_pListenCon;
        tcp::T * m_pTcp;
        udp::T * m_pUdp;

        // data consumer
        xos_net::i_connect * m_pUserData;

    public:
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 
        int set_tcp_listen();
        int set_tcp_data();
        int set_udp();

        bool tcp_listen() const;
        bool tcp_data() const;
        bool is_udp() const;

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 

        int set_none();
        int set_connect_failed();
        int set_connecting();
        int set_init_failed();
        int set_initing();
        int set_running();
        int set_need_close();
        int set_timeout();
        int set_closing();
        int set_closed();

        bool none() const;
        bool connect_failed() const;
        bool connecting() const;
        bool init_failed() const;
        bool initing() const;
        bool running() const;
        bool need_close() const;
        bool timeout() const;
        bool closing() const;
        bool closed() const;

        // socket的读写启用状态
        bool can_send() const;
        bool can_read() const;

    public:
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 
        // xos_aio::i_connect
        // 
        xos_aio::i_connect * create_accept_connect();

    public:
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 
        // net::i_connect
        // 

        int set_user_data( void * pUserData );
        void * get_user_data();

        int release_ref();
        int add_ref();

        const char * local_ip();
        const char * peer_ip();

        int local_port();
        int peer_port();

        bool is_tcp();

    protected:
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 

        int timeout_check();
        int init_data();

    public:
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 

        int post_init( xos_box::i_msg *& pMsg );
        int post_connect( xos_box::i_msg *& pMsg );
        int post_send( xos_box::i_msg *& pMsg, const char * lpszIp, int nPort, xos_box::i_buf *& pBuf, bool bCloseAfterSend, bool bQuitAfterSend );
        int post_send( xos_box::i_msg *& pMsg, xos_box::i_buf *& pBuf, bool bCloseAfterSend, bool bQuitAfterSend );
        int post_shutdown( xos_box::i_msg *& pMsg, int how );
        int post_close( xos_box::i_msg *& pMsg, bool bNotifyIfAlreadyClosed );
        int post_reset( xos_box::i_msg *& pMsg, bool bNotifyIfAlreadyClosed );

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 

        int set_timeout_time_s( int nSecond );
        xos_box::i_notify * notify() const;

        xos_aio::i_connect * aio_connect();
        net::i_connect * net_connect();

        int init();
        int term();

    };
} // xos_net

#endif // __DATA_STRUCT_CONNECTION_H__
